﻿//Copyright (C) 2009  Jaco & Slashshot & Slayer (ScionBot.com)

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Scion.Library;
using Scion.Library.Underlying;
using System.Drawing;
using Scion.Library.Antiban;
using Scion.Library.Advanced;

namespace Scion.Library.RS.UI
{
    /// <summary>
    /// Contains functions to manipulate the user interface.
    /// </summary>
    public class Interface : Determine
    {
        Superior super;
        Color[] statColours;

        /// <summary>
        /// Contains functions to manipulate the user interface.
        /// <param name="s">The instance of the bot.</param>
        /// </summary>
        public Interface(Superior s)
        {
            super = s;
            statColours = new Color[] { super.FromRGB(255, 255, 0), super.FromRGB(0, 255, 0), super.FromRGB(255, 152, 31), super.FromRGB(255, 0, 0) };
        }

        /// <summary>
        /// Sets the fight mode.
        /// </summary>
        /// <param name="mode">1 = Atttack, 2 = Strength, 3 = Defense, 4 = Mixed XP.</param>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool SetFightMode(int mode)
        {
            Rectangle rect;
            if (super.Tab.GetCurrentTab() != 1) super.Tab.SwitchTab(1);
            super.Sleep(new SleepRandom(400, 600));
            switch (mode)
            {
                case 1:
                    rect = new Rectangle(575, 255, 630, 290);
                    break;
                case 2:
                    rect = new Rectangle(660, 255, 710, 290);
                    break;
                case 3:
                    rect = new Rectangle(575, 310, 630, 345);
                    break;
                case 4:
                    rect = new Rectangle(660, 310, 710, 345);
                    break;
                default:
                    goto case 1;
            }
            int counter = 0;
            while ((counter < 4) && !Decide(super.FindColour(rect, super.FromRGB(124, 29, 27), 2)))
            {
                SizeRandom sr = new SizeRandom(new Size(rect.Width - rect.X, rect.Height - rect.Y), new Point(rect.X, rect.Y));
                super.Mouse.MoveClick(new PointRandom(sr.random.X, sr.random.Y, 0), true);
                super.Sleep(new SleepRandom(300, 400));
                counter++;
            }
            return Decide(super.FindColour(rect, super.FromRGB(124, 29, 27), 2));
        }

        /// <summary>
        /// Sets auto retaliate on or off.
        /// </summary>
        /// <param name="onOff">On = True, Off = False</param>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool SetRetaliate(bool onOff)
        {
            if (super.Tab.GetCurrentTab() != 1) super.Tab.SwitchTab(1);
            super.Sleep(new SleepRandom(400, 600));
            if (onOff ^ Decide(super.FindColour(new Rectangle(624, 385, 719, 396), super.FromRGB(124, 29, 27), 3)))
            {
                SizeRandom sr = new SizeRandom(new Size(719 - 24, 396 - 385), new Point(24, 385));
                super.Mouse.MoveClick(new PointRandom(sr.random.X, sr.random.Y, 0), true);
            }
            return true;
        }

        /// <summary>
        /// Sets run to on or off.
        /// </summary>
        /// <param name="onOff">On = True, Off = False</param>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool SetRun(bool onOff)
        {
            Point point = super.FindColour(new Rectangle(715, 105, 731, 110), super.FromRGB(234, 217, 104), 30);
            if (point == null && !onOff)
                goto End;
            if (Decide(point) && onOff) return false;
            if (!Decide(point) && !onOff) return false;
        End:
            SizeRandom sr = new SizeRandom(new Size(731 - 715, 110 - 105), new Point(715, 105));
            return super.Mouse.MoveClick(new PointRandom(sr.random.X, sr.random.Y, 0), true);
        }

        /// <summary>
        /// Clicks the Click here to continue label.
        /// </summary>
        public void ClickToContinue()
        {
            Point sr = new SizeRandom(new Size(141, 8), new Point(235, 450)).random;
            super.Mouse.MoveClick(new PointRandom(sr.X, sr.Y, 0), true);
        }

        /// <summary>
        /// Logs into the current account.
        /// </summary>
        /// <returns>Returns true if the login succeeded.</returns>
        public bool Login()
        {
            return super.Stub.botRandom.ProcessRandom("Login");
        }

        /// <summary>
        /// Logs the player out.
        /// </summary>
        /// <returns>Returns true if the log out succeeded.</returns>
        public bool LogOut()
        {
            if (!super.IsLoggedIn()) return false;
            ClickTab:
            if (!super.Tab.SwitchTab(14)) return false;
            super.Sleep(new SleepRandom(300, 400));
            if (super.Tab.GetCurrentTab() != 14)
                goto ClickTab;
            while (super.IsLoggedIn())
            {
                SizeRandom sr = new SizeRandom(new Size(704 - 575, 387 - 364), new Point(575, 364));
                super.Mouse.MoveClick(new PointRandom(sr.random.X, sr.random.Y, 0), true);
                super.Sleep(new SleepRandom(1000, 1200));
            }
            if (!super.IsLoggedIn())
            {
                super.Account.DisableAutoLogin = true;
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// Logs the player out and then terminates the thread.
        /// </summary>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool LogoutAndStop()
        {
            bool res = LogOut();
            if (!res)
                return res;
            super.Script.Stop();
            return true;
        }

        /// <summary>
        /// Gets the hitpoints of the current player.
        /// </summary>
        /// <returns>Returns how many hitpoints the player has left.</returns>
        public int GetHP()
        {
            try
            {
                return Convert.ToInt32(super.GetText(new Rectangle(725, 27, 740, 38), CharFont.StatChars, statColours, 5, true).Replace(" ", ""));
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// Gets the energy level of the current player.
        /// </summary>
        /// <returns>Returns how much energy the player has left.</returns>
        public int GetEnergy()
        {
            try
            {
                return Convert.ToInt32(super.GetText(new Rectangle(736, 104, 757, 116), CharFont.StatChars, statColours, 5, true).Replace(" ", ""));
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// Gets the prayer level of the current player.
        /// </summary>
        /// <returns>Returns how many prayer the player has left.</returns>
        public int GetPrayer()
        {
            try
            {
                return Convert.ToInt32(super.GetText(new Rectangle(738, 65, 757, 77), CharFont.StatChars, statColours, 5, true).Replace(" ", ""));
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// Sets the altitude of the camera.
        /// </summary>
        /// <param name="percent">The percent to set the camera at.</param>
        /// <returns>Return true if the camera is at the current altiude, or at the best it can get at.</returns>
        public bool SetCameraAltitude(double percent)
        {
            int prevAlt = 0;
            int alt = (int)((percent / 100) * -1237 - 1226);
            int curAlt = super.Reflection.GetCameraPositionZ();
            if (curAlt > alt)
            {
                super.Keyboard.HoldArrow(1);
                super.Sleep(new SleepRandom(300, 400));
                while (curAlt > alt)
                {
                    prevAlt = curAlt;
                    super.Sleep(new SleepRandom(200, 300));
                    curAlt = super.Reflection.GetCameraPositionZ();
                    if (prevAlt == curAlt)
                        break;
                }
                super.Sleep(new SleepRandom(100, 200));
                super.Keyboard.ReleaseArrow(1);
            }
            else
            {
                super.Keyboard.HoldArrow(2);
                super.Sleep(new SleepRandom(300, 400));
                while (curAlt < alt)
                {
                    prevAlt = curAlt;
                    super.Sleep(new SleepRandom(200, 300));
                    curAlt = super.Reflection.GetCameraPositionZ();
                    if (prevAlt == curAlt)
                        break;
                }
                super.Sleep(new SleepRandom(100, 200));
                super.Keyboard.ReleaseArrow(2);
            }
            return true;
        }

        /// <summary>
        /// Moves the compass to North, East, South or West.
        /// </summary>
        /// <param name="s">The position to move the compass to.</param>
        /// <returns>Returns true if the function succeeds.</returns>
        public bool RotateCompass(Compass s)
        {
            int compassAngle = super.Reflection.GetCompassAngle();
            int r = new Random().Next(1, 3);
            switch (s)
            {
                case Compass.North:
                    if (compassAngle >= 0 && compassAngle <= 100)
                        break;
                    super.Keyboard.HoldArrow(2 + r);
                    while (!(compassAngle >= 0 && compassAngle <= 100))
                    {
                        super.Sleep(new SleepRandom(20, 50));
                        compassAngle = super.Reflection.GetCompassAngle();
                    }
                    super.Keyboard.ReleaseArrow(2 + r);
                    break;
                case Compass.East:
                    if (compassAngle >= 500 && compassAngle <= 600)
                        break;
                    super.Keyboard.HoldArrow(2 + r);
                    while (!(compassAngle >= 500 && compassAngle <= 600))
                    {
                        super.Sleep(new SleepRandom(20, 50));
                        compassAngle = super.Reflection.GetCompassAngle();
                    }
                    super.Keyboard.ReleaseArrow(2 + r);
                    break;
                case Compass.South:
                    if (compassAngle >= 900 && compassAngle <= 1100)
                        break;
                    super.Keyboard.HoldArrow(2 + r);
                    while (!(compassAngle >= 900 && compassAngle <= 1100))
                    {
                        super.Sleep(new SleepRandom(20, 50));
                        compassAngle = super.Reflection.GetCompassAngle();
                    }
                    super.Keyboard.ReleaseArrow(2 + r);
                    break;
                case Compass.West:
                    if (compassAngle >= 1500 && compassAngle <= 1600)
                        break;
                    super.Keyboard.HoldArrow(2 + r);
                    while (!(compassAngle >= 1500 && compassAngle <= 1600))
                    {
                        super.Sleep(new SleepRandom(20, 50));
                        compassAngle = super.Reflection.GetCompassAngle();
                    }
                    super.Keyboard.ReleaseArrow(2 + r);
                    break;
            }
            return true;
        }
    }

    /// <summary>
    /// Position of the compass.
    /// </summary>
    public enum Compass
    {
        North = 0,
        East = 1,
        South = 2,
        West = 3,
    }
}
